package com.ourteam.product.requirement.api;

import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;

import org.apache.commons.lang.ArrayUtils;

import com.ourteam.frame.web.AbstractTreeNodeBuilder;
import com.ourteam.product.requirement.dao.IProductRequirementDAO;
import com.ourteam.product.requirement.dao.ProductRequirementDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductRequirementFeatureRelateDAOQueryBean;
import com.ourteam.product.requirement.dao.ProductVersionRelateDAOFactory;
import com.ourteam.product.requirement.dao.ProductVersionRelateDAOQueryBean;
import com.ourteam.product.requirement.domain.ProductElementTypeEnum;
import com.ourteam.product.requirement.domain.ProductRequirementBean;
import com.ourteam.product.requirement.service.IProductService;
import com.ourteam.product.requirement.service.ProductServiceFactory;

public class ProductRequirementSubNodeBuilder
		extends AbstractTreeNodeBuilder<ProductRequirementBean, ProductRequirementBean> {

	private static final IProductService PRODUCT_SERVICE = ProductServiceFactory.getProductService();

	private long productDefineId;

	private long productVersionId;

	@Override
	public ProductRequirementBean[] getTreeNodeObjects(ProductRequirementBean parentObject) throws Exception {

		long parentId = parentObject != null ? parentObject.getId() : 0;

		ProductRequirementDAOQueryBean qeryBean = new ProductRequirementDAOQueryBean();

		qeryBean.setSortProperty(IProductRequirementDAO.SortIndex);

		ProductRequirementDAOQueryBean.Criteria criteria = qeryBean.createCriteria();

		criteria.andProductDefineIdEqualTo(productDefineId).andParentIdEqualTo(parentId);

		if (productVersionId != 0) {
			ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

			versionRelateQueryBean.addProductElementIdSelectProperty();

			versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(productVersionId)
					.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_REQUIREMENT.getName());

			criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());
		}

		return PRODUCT_SERVICE.queryProductRequirements(qeryBean);
	}

	@Override
	public Object getNodeId(ProductRequirementBean childObject) throws Exception {
		return childObject.getId();
	}

	@Override
	public boolean isLeaf(ProductRequirementBean childObject) throws Exception {
		return childObject.getRequestType().equals("REQ_FACED") ? false : true;
	}

	@Override
	public String getTag(ProductRequirementBean childObject) throws Exception {

		if (childObject.getRequestType().equals("REQ_FACED")) {

			String coverageRate = "";

			ProductRequirementBean[] requirementBeans = getTreeNodeObjects(childObject);

			int childCount = 0;

			int relateFeatureCount = 0;

			if (ArrayUtils.isNotEmpty(requirementBeans)) {
				long[] requirementIds = new long[requirementBeans.length];

				for (int i = 0; i < requirementIds.length; i++) {
					requirementIds[i] = requirementBeans[i].getId();
				}

				childCount = requirementIds.length;

				ProductRequirementFeatureRelateDAOQueryBean queryBean = new ProductRequirementFeatureRelateDAOQueryBean();

				queryBean.createCriteria().andProductRequirementVersionIdEqualTo(productVersionId)
						.andProductRequirementIdIn(requirementIds);

				relateFeatureCount = PRODUCT_SERVICE.queryProductRequirementFeatureRelateCount(queryBean);

				if (relateFeatureCount > childCount) {
					coverageRate = "100%";
				} else if(relateFeatureCount == 0){
					coverageRate = "0%";
				}
				else {
					coverageRate = accuracy(relateFeatureCount,childCount, 1);
				}
			} else {
				coverageRate = "0%";
			}

			StringBuffer stringBuffer = new StringBuffer("功能覆盖率:");
			stringBuffer.append(coverageRate);
			return stringBuffer.toString();

		} else {
			ProductRequirementFeatureRelateDAOQueryBean queryBean = new ProductRequirementFeatureRelateDAOQueryBean();

			queryBean.createCriteria().andProductRequirementVersionIdEqualTo(productVersionId)
					.andProductRequirementIdEqualTo(childObject.getId());

			int count = PRODUCT_SERVICE.queryProductRequirementFeatureRelateCount(queryBean);

			return "已对应" + count + "个产品功能";
		}

	}

	@Override
	public int getChildCount(ProductRequirementBean childObject) throws Exception {
		ProductRequirementDAOQueryBean qeryBean = new ProductRequirementDAOQueryBean();

		ProductRequirementDAOQueryBean.Criteria criteria = qeryBean.createCriteria();

		criteria.andProductDefineIdEqualTo(productDefineId).andParentIdEqualTo(childObject.getId());

		if (productVersionId != 0) {
			ProductVersionRelateDAOQueryBean versionRelateQueryBean = new ProductVersionRelateDAOQueryBean();

			versionRelateQueryBean.addProductElementIdSelectProperty();

			versionRelateQueryBean.createCriteria().andProductVersionIdEqualTo(productVersionId)
					.andProductElementTypeEqualTo(ProductElementTypeEnum.PRODUCT_FEATURE.getName());

			criteria.andIdIn(versionRelateQueryBean, ProductVersionRelateDAOFactory.getProductVersionRelateDAO());
		}

		return PRODUCT_SERVICE.queryProductRequirementCount(qeryBean);
	}

	@Override
	public String getNodeDefineId(ProductRequirementBean childObject) throws Exception {
		return childObject.getRequestType();
	}

	@Override
	public ProductRequirementBean converToParentObject(Object parent) throws Exception {
		if (parent == null) {
			return null;
		} else {
			return PRODUCT_SERVICE.getProductRequirementById(Long.parseLong((String) parent));
		}

	}

	public long getProductDefineId() {
		return productDefineId;
	}

	public void setProductDefineId(long productDefineId) {
		this.productDefineId = productDefineId;
	}

	public long getProductVersionId() {
		return productVersionId;
	}

	public void setProductVersionId(long productVersionId) {
		this.productVersionId = productVersionId;
	}

	private static String accuracy(double num, double total, int scale) {
		DecimalFormat df = (DecimalFormat) NumberFormat.getInstance();
		// 可以设置精确几位小数
		df.setMaximumFractionDigits(scale);
		// 模式 例如四舍五入
		df.setRoundingMode(RoundingMode.HALF_UP);
		double accuracy_num = num / total * 100;
		return df.format(accuracy_num) + "%";
	}

}
